/*
 * @Description: 标签服务层
 * @Author: fhw
 * @Date: 2024-06-15
 */

import { Injectable, UseFilters } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { In, Repository } from 'typeorm';
import { TagEntity } from './entities/tag.entity';
import { CreateTagDto, UpdateTagDto, GetTagDto } from './dto/tag.dto';
import { HttpExceptionFilter } from 'src/common/http-exception.filter';
import { getPagination, throwHttp } from 'src/utlis';
import { isTrue } from 'src/utlis/tools';
import { IdDto } from 'src/common/dto/dto';

@Injectable()
export class TagsService {
  constructor(
    @InjectRepository(TagEntity)
    private readonly tagRepository: Repository<TagEntity>,
  ) { }

  /** 创建标签 */
  @UseFilters(new HttpExceptionFilter())
  async createTag(body: CreateTagDto) {
    try {
      const existingTag = await this.tagRepository.findOne({
        where: { name: body.name, lang: body.lang },
      });

      if (existingTag) {
        throwHttp('同一语言下标签名称已存在');
      }

      const tag = this.tagRepository.create({
        name: body.name,
        lang: body.lang,
      });
      const result = await this.tagRepository.save(tag);
      if (isTrue(result)) {
        return '标签创建成功';
      }
      throwHttp('标签创建失败');
    } catch (error) {
      throwHttp(error.message);
    }
  }

  /** 更新标签 */
  @UseFilters(new HttpExceptionFilter())
  async updateTag(body: UpdateTagDto) {
    try {
      const tagInfo = await this.tagRepository.findOne({
        where: { id: body.id },
      });

      if (!isTrue(tagInfo)) {
        throwHttp('标签不存在');
      }

      const existingTag = await this.tagRepository.findOne({
        where: { name: body.name, lang: body.lang, id: In([body.id]) },
      });

      if (existingTag) {
        throwHttp('同一语言下标签名称已存在');
      }

      const { affected } = await this.tagRepository
        .createQueryBuilder()
        .update(TagEntity)
        .set({
          name: body.name,
          lang: body.lang,
        })
        .where('id = :id', { id: body.id })
        .execute();

      if (affected) {
        return '标签更新成功';
      }
      throwHttp('标签更新失败');
    } catch (error) {
      throwHttp(error.message);
    }
  }

  /** 获取标签列表 */
  @UseFilters(new HttpExceptionFilter())
  async getTagPage(params: GetTagDto) {
    try {
      const { name, lang } = params;
      const where: GetTagDto = {
        name,
        lang,
      };

      // 过滤掉 `undefined` 的属性
      Object.keys(where).forEach((key) => where[key] === undefined && delete where[key]);

      const { pageSize, pageNum } = getPagination({
        pageSize: params.pageSize,
        pageNum: params.pageNum,
      });

      const [data, total] = await this.tagRepository.findAndCount({
        where,
        cache: true,
        skip: pageNum * pageSize, // 跳过的数量
        take: pageSize, // 每页的数量
        order: { createDate: 'DESC' }, // 排序
      });

      return {
        data,
        total,
        pageSize,
        pageNum: pageNum + 1,
      };
    } catch (error) {
      throwHttp(error.message);
    }
  }

  /** 获取标签详情 */
  @UseFilters(new HttpExceptionFilter())
  async getTagInfo(id: number) {
    try {
      const tag = await this.tagRepository.findOne({
        where: { id },
        cache: true,
      });

      if (!tag) {
        throwHttp('标签不存在');
      }

      return tag;
    } catch (error) {
      throwHttp(error.message);
    }
  }

  /** 删除标签 */
  @UseFilters(new HttpExceptionFilter())
  async deleteTag({ id }: IdDto) {
    try {
      const tag = await this.getTagInfo(id);
      if (!isTrue(tag)) {
        throwHttp('标签不存在');
      }

      await this.tagRepository.softDelete(id);
      return '标签删除成功';
    } catch (error) {
      throwHttp(error.message);
    }
  }
}
